package cn.iocoder.yudao.module.pplan.controller.admin.producerecord;

import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.module.pplan.controller.admin.producerecord.vo.*;
import cn.iocoder.yudao.module.pplan.dal.dataobject.producerecord.ProduceRecordDO;
import cn.iocoder.yudao.module.pplan.service.producerecord.ProduceRecordService;
import com.alibaba.fastjson.JSONObject;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.time.LocalDate;
import java.util.*;

import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

@Tag(name = "管理后台 - 生产计划-生产季度计划记录")
@RestController
@RequestMapping("/pplan/produce-record")
@Validated
@Slf4j
public class ProduceRecordController {

    @Resource
    private ProduceRecordService produceRecordService;

    @PostMapping("/create")
    @Operation(summary = "创建生产计划-生产季度计划记录")
    @PreAuthorize("@ss.hasPermission('pplan:produce-record:create')")
    public CommonResult<Long> createProduceRecord(@Valid @RequestBody ProduceRecordSaveReqVO createReqVO) {
        return success(produceRecordService.createProduceRecord(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新生产计划-生产季度计划记录")
    @PreAuthorize("@ss.hasPermission('pplan:produce-record:update')")
    public CommonResult<Boolean> updateProduceRecord(@Valid @RequestBody ProduceRecordSaveReqVO updateReqVO) {
        produceRecordService.updateProduceRecord(updateReqVO);
        return success(true);
    }

    @PutMapping("/update-status")
    @Operation(summary = "更新机供品餐具清洗计划清洗状态")
    public CommonResult<Boolean> updateProduceStatus(@Valid @RequestBody ProduceRecordUpdateStatusReqVO updateReqVO) {
        produceRecordService.updateProduceStatus(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除生产计划-生产季度计划记录")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('pplan:produce-record:delete')")
    public CommonResult<Boolean> deleteProduceRecord(@RequestParam("id") Long id) {
        produceRecordService.deleteProduceRecord(id);
        return success(true);
    }

    @DeleteMapping("/delete-list")
    @Parameter(name = "ids", description = "编号", required = true)
    @Operation(summary = "批量删除生产计划-生产季度计划记录")
                @PreAuthorize("@ss.hasPermission('pplan:produce-record:delete')")
    public CommonResult<Boolean> deleteProduceRecordList(@RequestParam("ids") List<Long> ids) {
        produceRecordService.deleteProduceRecordListByIds(ids);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得生产计划-生产季度计划记录")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('pplan:produce-record:query')")
    public CommonResult<ProduceRecordRespVO> getProduceRecord(@RequestParam("id") Long id) {
        ProduceRecordRespVO produceRecord = produceRecordService.getProduceRecord(id);
        return success(produceRecord);
    }

    @GetMapping("/getno")
    @Operation(summary = "获得生产计划-生产季度计划记录")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('pplan:produce-record:query')")
    public CommonResult<ProduceRecordRespVO> getProduceRecordByFn(@RequestParam("flightNo") String flightNo) {
        ProduceRecordRespVO produceRecord = produceRecordService.getProduceRecordByFn(flightNo);
        return success(produceRecord);
    }

    @GetMapping("/page")
    @Operation(summary = "获得生产计划-生产季度计划记录分页")
    @PreAuthorize("@ss.hasPermission('pplan:produce-record:query')")
    public CommonResult<PageResult<ProduceRecordRespVO>> getProduceRecordPage(@Valid ProduceRecordPageReqVO pageReqVO) {
        PageResult<ProduceRecordDO> pageResult = produceRecordService.getProduceRecordPage(pageReqVO);
        return success(BeanUtils.toBean(pageResult, ProduceRecordRespVO.class));
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出生产计划-生产季度计划记录 Excel")
    @PreAuthorize("@ss.hasPermission('pplan:produce-record:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportProduceRecordExcel(@Valid ProduceRecordPageReqVO pageReqVO,
              HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<ProduceRecordDO> list = produceRecordService.getProduceRecordPage(pageReqVO).getList();
        // 导出 Excel
        ExcelUtils.write(response, "生产计划-生产季度计划记录.xls", "数据", ProduceRecordRespVO.class,
                        BeanUtils.toBean(list, ProduceRecordRespVO.class));
    }

    @GetMapping("/statistics")
    @Operation(summary = "获得生产记录统计信息")
    public CommonResult<Object> getProduceRecordStatistics2() {
        ProduceRecordPageReqVO pageReqVO = new ProduceRecordPageReqVO();
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<ProduceRecordDO> produceRecords = produceRecordService.getProduceRecordPage(pageReqVO).getList();
        Map<String, Map<LocalDate, Integer>> flightStatistics = new HashMap<>();

        // 确定最小和最大的日期
        LocalDate startDate = null;
        LocalDate endDate = null;

        for (ProduceRecordDO record : produceRecords) {
            LocalDate createTime = record.getCreateTime().toLocalDate();
            if (createTime != null) {
                if (startDate == null || createTime.isBefore(startDate)) {
                    startDate = createTime;
                }
                if (endDate == null || createTime.isAfter(endDate)) {
                    endDate = createTime;
                }
            }
        }

        // 如果没有找到任何记录，则直接返回空结果
        if (startDate == null || endDate == null) {
            log.info("flightStatistics: {}", JSONObject.toJSONString(flightStatistics));
            return success(flightStatistics);
        }

        // 初始化所有航班的日期统计
        for (ProduceRecordDO record : produceRecords) {
            String flightNo = record.getFlightNo();
            LocalDate createTime = record.getCreateTime().toLocalDate();
            if (flightNo == null || createTime == null) {
                continue;
            }
            flightStatistics.putIfAbsent(flightNo, new HashMap<>());
            for (LocalDate date = startDate; !date.isAfter(endDate); date = date.plusDays(1)) {
                flightStatistics.get(flightNo).putIfAbsent(date, 0);
            }
        }

        // 累加餐食数量到相应的日期
        for (ProduceRecordDO record : produceRecords) {
            String flightNo = record.getFlightNo();
            LocalDate createTime = record.getCreateTime().toLocalDate();
            if (flightNo == null || createTime == null) {
                continue;
            }

            // 计算该记录的餐食总数
            int totalMealQty = 0;
            totalMealQty += record.getBussClassMealQty() != null ? record.getBussClassMealQty() : 0;
            totalMealQty += record.getPremEcoClassMealQty() != null ? record.getPremEcoClassMealQty() : 0;
            totalMealQty += record.getEcoClassMealQty() != null ? record.getEcoClassMealQty() : 0;
            totalMealQty += record.getCrewMealQty() != null ? record.getCrewMealQty() : 0;
            totalMealQty += record.getBussClassSpcMealQty() != null ? record.getBussClassSpcMealQty() : 0;
            totalMealQty += record.getPremEcoClassSpcMealQty() != null ? record.getPremEcoClassSpcMealQty() : 0;
            totalMealQty += record.getEcoClassSpcMealQty() != null ? record.getEcoClassSpcMealQty() : 0;
            totalMealQty += record.getCrewSpcMealQty() != null ? record.getCrewSpcMealQty() : 0;

            flightStatistics.get(flightNo).merge(createTime, totalMealQty, Integer::sum);
        }

        log.info("flightStatistics: {}", JSONObject.toJSONString(flightStatistics));

        return success(flightStatistics);
    }




}
